import 'dart:developer' as developer;
import 'dart:convert';
import '../models/api_response.dart';
import '../models/user_model.dart';
import '../services/api_service.dart';
import '../constants/api_endpoints.dart';
import '../../shared/storage/storage_service.dart';

class AuthRepository {
  final ApiService _apiService;
  final StorageService _storageService;

  AuthRepository(this._apiService, this._storageService);

  Future<ApiResponse<UserModel>> login({
    required String username,
    required String password,
  }) async {
    // 尝试使用 /auth/login（生成真实 JWT token）
    // 如果失败，可以回退到 /im/auth/login
    final response = await _apiService.post<Map<String, dynamic>>(
      ApiEndpoints.authLogin,
      data: {
        'username': username,  // 注意：这个接口使用 username 而不是 user_name
        'password': password,
      },
      fromJson: (json) => json as Map<String, dynamic>,
    );

    if (response.success && response.data != null) {
      final data = response.data!;
      
      // 保存 token - 支持多种可能的字段名
      String? tokenStr;
      if (data['token'] != null) {
        tokenStr = data['token'].toString();
      } else if (data['access_token'] != null) {
        tokenStr = data['access_token'].toString();
      } else if (data['accessToken'] != null) {
        tokenStr = data['accessToken'].toString();
      }
      
      if (tokenStr != null && tokenStr.isNotEmpty) {
        await _storageService.saveToken(tokenStr);
        // 验证 token 是否保存成功
        final savedToken = await _storageService.getToken();
        if (savedToken == null || savedToken != tokenStr) {
          throw Exception('Token 保存失败: 保存前=$tokenStr, 保存后=$savedToken');
        }
        // 调试日志：确认 token 已保存
        developer.log(
          '✅ Token saved successfully: ${tokenStr.substring(0, tokenStr.length > 20 ? 20 : tokenStr.length)}...',
          name: 'AuthRepository',
        );
      } else {
        throw Exception('登录响应中未找到有效的 token，响应数据: $data');
      }
      
      // 保存 subscription_id（用于WebSocket连接）
      if (data['subscription_id'] != null) {
        final subscriptionId = data['subscription_id'].toString();
        await _storageService.saveSubscriptionId(subscriptionId);
        developer.log('✅ Subscription ID saved: $subscriptionId', name: 'AuthRepository');
      } else {
        developer.log('⚠️ No subscription_id in login response', name: 'AuthRepository');
      }
      
      // 保存用户信息
      if (data['user'] != null) {
        try {
          final userData = data['user'] as Map<String, dynamic>;
          developer.log('📝 Saving user info: ${userData.keys}', name: 'AuthRepository');
          
          final user = UserModel.fromJson(userData);
          await _storageService.saveUserId(user.id);
          
          // 改进：使用 JSON 序列化保存用户信息，而不是 toString()
          final userJson = jsonEncode(userData);
          await _storageService.saveUserInfo(userJson);
          
          // 验证保存是否成功
          final savedUserInfo = await _storageService.getUserInfo();
          if (savedUserInfo != null && savedUserInfo == userJson) {
            developer.log('✅ User info saved successfully: ${user.username} (ID: ${user.id})', name: 'AuthRepository');
          } else {
            developer.log('⚠️ User info save verification failed', name: 'AuthRepository');
          }
          
          // 返回用户模型
          return ApiResponse<UserModel>(
            code: response.code,
            message: response.message,
            data: user,
            success: true,
          );
        } catch (e, stackTrace) {
          developer.log('❌ Failed to save user info: $e', name: 'AuthRepository');
          developer.log('Stack trace: $stackTrace', name: 'AuthRepository');
          throw Exception('保存用户信息失败: $e');
        }
      } else {
        developer.log('⚠️ No user data in login response: ${data.keys}', name: 'AuthRepository');
      }
    }

    return ApiResponse<UserModel>(
      code: response.code,
      message: response.message,
      success: false,
    );
  }

  Future<ApiResponse<UserModel>> register({
    required String username,
    required String password,
    String? email,
    String? phone,
  }) async {
    final response = await _apiService.post<UserModel>(
      ApiEndpoints.authRegister,
      data: {
        'username': username,
        'password': password,
        'email': email,
        'phone': phone,
      },
      fromJson: (json) => UserModel.fromJson(json as Map<String, dynamic>),
    );

    return response;
  }

  Future<ApiResponse<void>> logout() async {
    try {
      // 清理所有本地存储数据
      await _storageService.clearAll();
      
      // 注意：WebSocket 连接的清理应该在 ViewModel 中处理
      // 因为 Repository 不应该直接依赖 Service
      
      return ApiResponse(
        code: 200,
        message: 'Logout success',
        success: true,
      );
    } catch (e) {
      return ApiResponse(
        code: 500,
        message: 'Logout failed: $e',
        success: false,
      );
    }
  }

  Future<bool> isLoggedIn() async {
    final token = await _storageService.getToken();
    return token != null && token.isNotEmpty;
  }

  /// 更新用户信息
  Future<ApiResponse<UserModel>> updateUserProfile({
    String? name,
    String? phone,
    int? gender,
    String? abstractField,
    String? fileName,
  }) async {
    final updateData = <String, dynamic>{};
    
    if (name != null) {
      updateData['name'] = name;
    }
    if (phone != null) {
      updateData['phone'] = phone.isEmpty ? null : phone;
    }
    if (gender != null) {
      updateData['gender'] = gender;
    }
    if (abstractField != null) {
      updateData['abstract_field'] = abstractField.isEmpty ? null : abstractField;
    }
    if (fileName != null) {
      updateData['file_name'] = fileName;
    }

    final response = await _apiService.put<UserModel>(
      ApiEndpoints.usersMeUpdate,
      data: updateData,
      fromJson: (json) => UserModel.fromJson(json as Map<String, dynamic>),
    );

    if (response.success && response.data != null) {
      // 更新本地存储的用户信息
      final user = response.data!;
      final userJson = jsonEncode(user.toJson());
      await _storageService.saveUserInfo(userJson);
      await _storageService.saveUserId(user.id);
      
      developer.log('✅ User profile updated: ${user.username}', name: 'AuthRepository');
    }

    return response;
  }
}

